// ignore_for_file: must_be_immutable

/*
 * @Author: ZephyrGao
 * @Date: 2023-11-03 11:35:12
 * @Description: 
 * Copyright (c) 2023 by ZephyrGao, All Rights Reserved. 
 */

import 'dart:developer';

import 'package:cn_flutter_ui/src/constants/vant4_badge_constant.dart';
import 'package:cn_flutter_ui/src/constants/vant4_common_constant.dart';
import 'package:flutter/material.dart';

extension VanBadgePositionExtension on VanBadgePosition {
  // badge
  double get left => [0.0, 1.0, 1.0, 0.0][index];
  double get top => [0.0, 0.0, 1.0, 1.0][index];
  // 底座
  double get hLeft => [1.0, 0.0, 0.0, 1.0][index];
  double get hTop => [1.0, 1.0, 0.0, 0.0][index];
  // dx dy

  double get dx => [-1.0, 1.0, 1.0, -1.0][index];
  double get dy => [-1.0, -1.0, 1.0, 1.0][index];
}

enum VanBadgePosition {
  topLeft,
  topRight,
  bottomRight,
  bottomLeft,
}

class VanBadge extends StatefulWidget {
  VanBadge({
    super.key,
    this.content,
    this.color = Vant4BadgeConstant.color,
    this.textColor = Vant4BadgeConstant.textColor,
    this.fontSize = Vant4BadgeConstant.fontSize,
    this.dot = false,
    this.max,
    this.offset = const Offset(0, 0),
    this.showZero = true,
    this.position = VanBadgePosition.topRight,
    this.defaultSlots,
    this.contentSlots,
  })  : assert(content == null || content is String || content is int,
            'content must be null, int, or String'),
        assert(max == null || max is String || max is int,
            'max must be null, int, or String');

  /// 徽标内容
  dynamic content;

  /// 徽标背景颜色
  final Color color;

  /// 徽标文字颜色
  final Color textColor;

  /// 徽标文字大小
  final double fontSize;

  /// 是否展示为小红点
  final bool dot;

  /// 最大值，超过最大值会显示 {max}+，仅当 content 为数字时有效
  dynamic max;

  /// 设置徽标的偏移量，数组的两项分别对应水平向右和垂直向下方向的偏移量
  final Offset offset;

  /// 当 content 为数字 0 或字符串 '0' 时，是否展示徽标
  final bool showZero;

  /// 徽标位置，可选值为 `topLeft`  `topRight`  `bottomLeft`  `bottomRight`
  final VanBadgePosition position;

  /// 徽标包裹的子元素
  final Widget? defaultSlots;

  /// 自定义徽标内容
  final Widget? contentSlots;

  @override
  State<VanBadge> createState() => _VanBadgeState();
}

class _VanBadgeState extends State<VanBadge> {
  final GlobalKey _holderKey = GlobalKey(debugLabel: '_holderKey');
  final GlobalKey _badgeKey = GlobalKey(debugLabel: '_badgeKey');
  // badge底座的大小
  Size holderSize = Size.zero;
  // badge大小
  Size badgeSize = Size.zero;
  double? leftPosition;
  double? rightPosition;
  double? topPosition;
  double? bottomPosition;

  @override
  void initState() {
    super.initState();
    _getSize();
  }

  @override
  void didUpdateWidget(covariant VanBadge oldWidget) {
    super.didUpdateWidget(oldWidget);
    _getSize();
  }

  @override
  Widget build(BuildContext context) {
    double width = holderSize.width;
    double height = holderSize.height;
    width = holderSize.width +
        (widget.dot ? (Vant4BadgeConstant.dotWidth) : badgeSize.width) * 0.5;
    height = holderSize.height +
        (widget.dot ? Vant4BadgeConstant.dotHeight : badgeSize.height) * 0.5;

    if (width < 0) width = 0;
    if (height < 0) height = 0;
    if (_badgeShow()) {
      width = width + widget.position.dx * widget.offset.dx;
      width = width < holderSize.width ? holderSize.width : width;
      height = height + widget.position.dy * widget.offset.dy;
      height = height < holderSize.height ? holderSize.height : height;
    }

    return SizedBox(
      width: width,
      height: height,
      child: Stack(
        children: [_buildHolder(), _buildBadge()],
      ),
    );
  }

  Widget _buildHolder() {
    double w = widget.dot ? Vant4BadgeConstant.dotWidth : badgeSize.width;
    double h = widget.dot ? Vant4BadgeConstant.dotHeight : badgeSize.height;
    double left = widget.position.hLeft * w * 0.5;
    double top = widget.position.hTop * h * 0.5;
    if (_badgeShow()) {
      // 左侧badge & 左移
      if (widget.position.dx < 0) {
        left = left + widget.position.dx * widget.offset.dx;
        left = left < 0 ? 0 : left;
      }
      if (widget.position.dy < 0) {
        top = top + widget.position.dy * widget.offset.dy;
        top = top < 0 ? 0 : top;
      }
    }

    // 底座容器大小
    return Positioned(
        left: left,
        top: top,
        child: Container(
          key: _holderKey,
          child: widget.defaultSlots ?? Vant4CommonConstant.empty,
        ));
  }

  Widget _buildBadge() {
    double w = widget.dot ? Vant4BadgeConstant.dotWidth : badgeSize.width;
    double h = widget.dot ? Vant4BadgeConstant.dotHeight : badgeSize.height;
    double left = widget.position.left * (holderSize.width - w * 0.5);
    double top = widget.position.top * (holderSize.height - h * 0.5);
    if (widget.position.dx < 0) {
      if (widget.offset.dx > w * 0.5) {
        left = (widget.offset.dx - w * 0.5);
      }
    } else {
      left = left + widget.position.dx * widget.offset.dx;
    }
    if (widget.position.dy < 0) {
      if (widget.offset.dy > h * 0.5) {
        top = (widget.offset.dy - h * 0.5);
      }
    } else {
      top = top + widget.position.dy * widget.offset.dy;
    }

    return Positioned(
        left: left,
        top: top,
        child: widget.dot ? _dotWidget() : _badgeWidget());
  }

  Size _getHolderSize() {
    BuildContext? context = _holderKey.currentContext;
    if (context == null) return Size.zero;
    final RenderBox renderBox =
        _holderKey.currentContext?.findRenderObject() as RenderBox;
    return renderBox.size;
  }

  Size _getBadgeSize() {
    BuildContext? context = _badgeKey.currentContext;
    if (context == null) return Size.zero;
    final RenderBox renderBox =
        _badgeKey.currentContext?.findRenderObject() as RenderBox;
    return renderBox.size;
  }

  Widget _badgeWidget() {
    if (widget.max != null && widget.content != null) {
      int? max = int.tryParse(widget.max.toString());
      int? content = int.tryParse(widget.content.toString());
      if (max is int && content is int && content > max) {
        widget.content = "$max+";
      }
    }

    return SizedBox(
        key: _badgeKey,
        child: widget.contentSlots ??
            (_showContent()
                ? Container(
                    alignment: Alignment.center,
                    padding: Vant4BadgeConstant.padding,
                    constraints: const BoxConstraints(
                        minWidth: Vant4BadgeConstant.minWidth),
                    decoration: BoxDecoration(
                      color: widget.color,
                      border: Vant4BadgeConstant.border,
                      borderRadius: Vant4BadgeConstant.radius,
                    ),
                    child: Text(
                      "${widget.content ?? ""}",
                      style: TextStyle(
                        color: widget.textColor,
                        fontSize: widget.fontSize,
                        fontWeight: FontWeight.w600,
                      ),
                    ),
                  )
                : Vant4CommonConstant.empty));
  }

  Widget _dotWidget() {
    return Container(
      width: Vant4BadgeConstant.dotWidth,
      height: Vant4BadgeConstant.dotHeight,
      decoration: BoxDecoration(
        color: widget.color,
        shape: BoxShape.circle,
      ),
    );
  }

  void _getSize() {
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      if (mounted) {
        holderSize = _getHolderSize();
        badgeSize = _getBadgeSize();
        setState(() {});
      }
    });
  }

  bool _badgeShow() {
    return _showContent() || widget.dot;
  }

  bool _showContent() {
    if (widget.content != null && widget.content.toString().isNotEmpty) {
      if (!widget.showZero && widget.content.toString() == '0') {
        return false;
      }
      return true;
    }
    return false;
  }
}
